package services;

import java.util.Collection;
import java.util.Date;
import java.util.HashSet;

import javax.transaction.Transactional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import repositories.ReunionRepository;
import domain.Acta;
import domain.Administrador;
import domain.ComunidadDeVecinos;
import domain.Reunion;
import domain.Vecino;

@Service
@Transactional
public class ReunionService {

	// Managed Repository
	@Autowired
	private ReunionRepository reunionRepository;
	
	// Supporting Services
	@Autowired
	private ComunidadDeVecinosService comunidadDeVecinosService;
	
	@Autowired
	private VecinoService vecinoService;
	@Autowired
	private AdministradorService administradorService;

	// Constructor
	public ReunionService() {
		super();
	}

	// Simple CRUD methods

	public Reunion create(ComunidadDeVecinos cv) {
		Assert.notNull(cv);

		Vecino vecino;
		Reunion res;
		Collection<Vecino> asistentes;
		
		Assert.isTrue(vecinoService.findByPrincipal() instanceof Vecino);


		vecino = vecinoService.findByPrincipal();
		Assert.isTrue(vecino.equals(cv.getPresidente()));
		asistentes = new HashSet<Vecino>();

		res = new Reunion();

		res.setAsistentes(asistentes);
		res.setPresidente(vecinoService.findByPrincipal());
		res.setComunidadDeVecinos(cv);
		res.setActas(new HashSet<Acta>());

		return res;
	}

	public Reunion save(Reunion reunion) {
		Assert.notNull(reunion);
		Reunion res;
		Date currentMoment;
		Vecino principal;

		currentMoment = new Date();
		Assert.isTrue(reunion.getFechaCelebracion().after(currentMoment));
		principal = vecinoService.findByPrincipal();
		Assert.isTrue(principal instanceof Vecino);
		
		if(reunion.getId()==0){
			Assert.isTrue(principal.equals(reunion.getComunidadDeVecinos().getPresidente()));

		}
		
		res = reunionRepository.save(reunion);

		return res;
	}

	// Other Business methods

	public Collection<Reunion> findByCommunity(int comunidadId) {
		
		Collection<Reunion> res;
		Assert.isTrue(administradorService.findByPrincipal() instanceof Administrador);

		res = reunionRepository.findByCommunity(comunidadId);
		
		return res;
	}

	public Reunion findOne(int reunionId) {
		Reunion res;
		res = reunionRepository.findOne(reunionId);
		Assert.notNull(res);
		return res;
	}

	public Collection<Reunion> findByCommunityVecino(int comunidadId) {
		Collection<Reunion> res;
		Vecino principal;
		ComunidadDeVecinos comunidad;

		comunidad = comunidadDeVecinosService.findOne(comunidadId);
		principal = vecinoService.findByPrincipal();

		Assert.isTrue(comunidad.getVecinos().contains(principal));

		res = reunionRepository.findByCommunity(comunidadId);
		return res;
	}

	public Boolean isJoined(int reunionId) {
		Reunion reunion;
		Boolean res;
		reunion = findOne(reunionId);
		Vecino principal = vecinoService.findByPrincipal();
		res = reunion.getAsistentes().contains(principal);
		return res;
	}

	public void join(int reunionId) {
		Reunion reunion;
		Vecino principal;
		Collection<Vecino> asistentes;
		Date actual;

		actual = new Date();

		principal = vecinoService.findByPrincipal();
		reunion = findOne(reunionId);
		asistentes = reunion.getAsistentes();
		Assert.isTrue(reunion.getFechaCelebracion().after(actual));

		Assert.isTrue(!asistentes.contains(principal));

		asistentes.add(principal);
		save(reunion);

	}

	public void delete(Reunion r) {
		Assert.notNull(r);
		reunionRepository.delete(r);
		
	}
}
